﻿package Resource
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	import Util.*;
	/**
	 * ...
	 * @author Lissa Avery
	 */
	public class Tile 
	{
			
		[Embed(source = '../../graphics/bgWorldTiles.png')]
		private static var worldTiles:Class;
		public static const WORLD_TILES:SpriteSheet = new SpriteSheet(new worldTiles(), 7, 3);
		
		[Embed(source = '../../graphics/bgWaterPlains.png')]
		private static var waterPlains:Class;
		public static const WATER_PLAINS:SpriteSheet = new SpriteSheet(new waterPlains(), 3, 5);
		
		[Embed(source = '../../graphics/bgWaterTundra.png')]
		private static var waterTundra:Class;
		public static const WATER_TUNDRA:SpriteSheet = new SpriteSheet(new waterTundra(), 3, 5);
		
		[Embed(source = '../../graphics/bgWaterForest.png')]
		private static var waterForest:Class;
		public static const WATER_FOREST:SpriteSheet = new SpriteSheet(new waterForest(), 3, 5);
		
		[Embed(source = '../../graphics/bgWaterJungle.png')]
		private static var waterJungle:Class;
		public static const WATER_JUNGLE:SpriteSheet = new SpriteSheet(new waterJungle(), 3, 5);
		
		[Embed(source = '../../graphics/bgWaterMountains.png')]
		private static var waterMountains:Class;
		public static const WATER_MOUNTAINS:SpriteSheet = new SpriteSheet(new waterMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgWaterDesert.png')]
		private static var waterDesert:Class;
		public static const WATER_DESERT:SpriteSheet = new SpriteSheet(new waterDesert(),3, 5);
		
		[Embed(source = '../../graphics/bgPlainsTundra.png')]
		private static var plainsTundra:Class;
		public static const PLAINS_TUNDRA:SpriteSheet = new SpriteSheet(new plainsTundra(), 3, 5);
		
		[Embed(source = '../../graphics/bgPlainsDesert.png')]
		private static var plainsDesert:Class;
		public static const PLAINS_DESERT:SpriteSheet = new SpriteSheet(new plainsDesert(), 3, 5);
		
		[Embed(source = '../../graphics/bgPlainsForest.png')]
		private static var plainsForest:Class;
		public static const PLAINS_FOREST:SpriteSheet = new SpriteSheet(new plainsForest(), 3, 5);
		
		[Embed(source = '../../graphics/bgPlainsJungle.png')]
		private static var plainsJungle:Class;
		public static const PLAINS_JUNGLE:SpriteSheet = new SpriteSheet(new plainsJungle(), 3, 5);
		
		[Embed(source = '../../graphics/bgPlainsMountains.png')]
		private static var plainsMountains:Class;
		public static const PLAINS_MOUNTAINS:SpriteSheet = new SpriteSheet(new plainsMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgForestJungle.png')]
		private static var forestJungle:Class;
		public static const FOREST_JUNGLE:SpriteSheet = new SpriteSheet(new forestJungle(), 3, 5);
		
		[Embed(source = '../../graphics/bgForestMountains.png')]
		private static var forestMountains:Class;
		public static const FOREST_MOUNTAINS:SpriteSheet = new SpriteSheet(new forestMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgTundraDesert.png')]
		private static var tundraDesert:Class;
		public static const TUNDRA_DESERT:SpriteSheet = new SpriteSheet(new tundraDesert(), 3, 5);
		
		[Embed(source = '../../graphics/bgTundraForest.png')]
		private static var tundraForest:Class;
		public static const TUNDRA_FOREST:SpriteSheet = new SpriteSheet(new tundraForest(), 3, 5);
		
		[Embed(source = '../../graphics/bgTundraJungle.png')]
		private static var tundraJungle:Class;
		public static const TUNDRA_JUNGLE:SpriteSheet = new SpriteSheet(new tundraJungle(), 3, 5);
		
		[Embed(source = '../../graphics/bgTundraMountains.png')]
		private static var tundraMountains:Class;
		public static const TUNDRA_MOUNTAINS:SpriteSheet = new SpriteSheet(new tundraMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgDesertForest.png')]
		private static var desertForest:Class;
		public static const DESERT_FOREST:SpriteSheet = new SpriteSheet(new desertForest(), 3, 5);
		
		[Embed(source = '../../graphics/bgDesertJungle.png')]
		private static var desertJungle:Class;
		public static const DESERT_JUNGLE:SpriteSheet = new SpriteSheet(new desertJungle(), 3, 5);
		
		[Embed(source = '../../graphics/bgDesertMountains.png')]
		private static var desertMountains:Class;
		public static const DESERT_MOUNTAINS:SpriteSheet = new SpriteSheet(new desertMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgJungleMountains.png')]
		private static var jungleMountains:Class;
		public static const JUNGLE_MOUNTAINS:SpriteSheet = new SpriteSheet(new jungleMountains(), 3, 5);
		
		[Embed(source = '../../graphics/bgTransPlains.png')]
		private static var transPlains:Class;
		public static const TRANS_PLAINS:SpriteSheet = new SpriteSheet(new transPlains(), 3, 4);
		
		[Embed(source = '../../graphics/bgTransTundra.png')]
		private static var transTundra:Class;
		public static const TRANS_TUNDRA:SpriteSheet = new SpriteSheet(new transTundra(), 3, 4);
		
		[Embed(source = '../../graphics/bgTransForest.png')]
		private static var transForest:Class;
		public static const TRANS_FOREST:SpriteSheet = new SpriteSheet(new transForest(), 3, 4);
		
		[Embed(source = '../../graphics/bgTransJungle.png')]
		private static var transJungle:Class;
		public static const TRANS_JUNGLE:SpriteSheet = new SpriteSheet(new transJungle(), 3, 4);
		
		[Embed(source = '../../graphics/bgTransDesert.png')]
		private static var transDesert:Class;
		public static const TRANS_DESERT:SpriteSheet = new SpriteSheet(new transDesert(), 3, 4);
		
		[Embed(source = '../../graphics/bgTransMountains.png')]
		private static var transMountains:Class;
		public static const TRANS_MOUNTAINS:SpriteSheet = new SpriteSheet(new transMountains(), 3, 4);
		
		private static var comboTiles:Object = {
			(comboTileKey(Biome.WATER, Biome.PLAINS)):WATER_PLAINS,
			(comboTileKey(Biome.WATER, Biome.TUNDRA)):WATER_TUNDRA,
			(comboTileKey(Biome.WATER, Biome.FOREST)):WATER_FOREST,
			(comboTileKey(Biome.WATER, Biome.JUNGLE)):WATER_JUNGLE,
			(comboTileKey(Biome.WATER, Biome.MOUNTAINS)):WATER_MOUNTAINS,
			(comboTileKey(Biome.WATER, Biome.DESERT)):WATER_DESERT,
			(comboTileKey(Biome.PLAINS, Biome.FOREST)):PLAINS_FOREST,
			(comboTileKey(Biome.PLAINS, Biome.DESERT)):PLAINS_DESERT,
			(comboTileKey(Biome.PLAINS, Biome.JUNGLE)):PLAINS_JUNGLE,
			(comboTileKey(Biome.PLAINS, Biome.TUNDRA)):PLAINS_TUNDRA,
			(comboTileKey(Biome.PLAINS, Biome.MOUNTAINS)):PLAINS_MOUNTAINS,
			(comboTileKey(Biome.DESERT, Biome.FOREST)):DESERT_FOREST,
			(comboTileKey(Biome.DESERT, Biome.JUNGLE)):DESERT_JUNGLE,
			(comboTileKey(Biome.DESERT, Biome.MOUNTAINS)):DESERT_MOUNTAINS,
			(comboTileKey(Biome.TUNDRA, Biome.DESERT)):TUNDRA_DESERT,
			(comboTileKey(Biome.TUNDRA, Biome.FOREST)):TUNDRA_FOREST,
			(comboTileKey(Biome.TUNDRA, Biome.JUNGLE)):TUNDRA_JUNGLE,
			(comboTileKey(Biome.TUNDRA, Biome.MOUNTAINS)):TUNDRA_MOUNTAINS,
			(comboTileKey(Biome.FOREST, Biome.JUNGLE)):FOREST_JUNGLE,
			(comboTileKey(Biome.FOREST, Biome.MOUNTAINS)):FOREST_MOUNTAINS,			
			(comboTileKey(Biome.JUNGLE, Biome.MOUNTAINS)):JUNGLE_MOUNTAINS
		}
		
		private static var transTiles:Object = {
			(Biome.PLAINS.valueOf()):TRANS_PLAINS,
			(Biome.DESERT.valueOf()):TRANS_DESERT,
			(Biome.TUNDRA.valueOf()):TRANS_TUNDRA,
			(Biome.FOREST.valueOf()):TRANS_FOREST,
			(Biome.JUNGLE.valueOf()):TRANS_JUNGLE,
			(Biome.MOUNTAINS.valueOf()):TRANS_MOUNTAINS
		}
		
		private static var diagonalTiles:Object = {
			([[1, 0], [0, 0]]):new Point(1, 2),
			([[0, 1], [0, 0]]):new Point(0, 2),
			([[0, 0], [1, 0]]):new Point(1, 0),
			([[0, 0], [0, 1]]):new Point(0, 0),			
			([[1, 1], [0, 0]]):new Point(2, 2),			
			([[1, 1], [1, 0]]):new Point(2, 0),			
			([[1, 1], [0, 1]]):new Point(3, 0),			
			([[0, 1], [1, 1]]):new Point(3, 1),			
			([[0, 0], [1, 1]]):new Point(3, 2),			
			([[0, 1], [0, 1]]):new Point(0, 1),			
			([[1, 0], [1, 0]]):new Point(1, 1),
			([[1, 0], [1, 1]]):new Point(2, 1),
			([[1, 0], [0, 1]]):new Point(4, 0),
			([[0, 1], [1, 0]]):new Point(4, 1),
			([[0, 0], [0, 0]]):new Point(100, 100)	
		}
		
		private static function comboTileKey(lowerBiome:int, higherBiome:int):int {
			return lowerBiome * 10 + higherBiome;
		}
		
		public static function getComboTile(firstBiome:int, secondBiome:int):SpriteSheet {
			if (firstBiome < secondBiome) {
				return SpriteSheet(comboTiles[comboTileKey(firstBiome, secondBiome)]);
			} else {
				return SpriteSheet(comboTiles[comboTileKey(secondBiome, firstBiome)]);
			}
		}
		
		public static function copyDiagonalTile(biomes:Array, target:BitmapData, targetx:int, targety:int):void {
			var reducedBiomes:Array = getReducedBiomeSet(biomes);
			copyCombinedTile(reducedBiomes, biomes, target, targetx, targety);
		}
		
		private static function getReducedBiomeSet(biomes:Array):Array {
			var reducedBiomes:Array = new Array()
			var reducedBaseBiome:Array = new Array(biomes.length);
			
			//var lowestIndex:Point = new Point();
			var lowest:int = Biome.MOUNTAINS + 1;
			//var secondLowestIndex:Point = new Point();
			var secondLowest:int = Biome.MOUNTAINS + 1;
			
			// Get the lowest biome
			for (var i:int = 0; i < biomes.length; i++) {
				reducedBaseBiome[i] = new Array(biomes[i].length);
				for (var j:int = 0; j < (biomes[i] as Array).length; j++) {
					//trace("biomes[i][j] < secondLowest: " + (biomes[i][j] < secondLowest));
					if (biomes[i][j] < secondLowest) {
						//trace("biomes[i][j] > lowest: " + (biomes[i][j] > lowest));
						//trace("biomes[i][j] < lowest: " + (biomes[i][j] < lowest));
						if (biomes[i][j] > lowest) {
							secondLowest = biomes[i][j];
							//secondLowestIndex = new Point(i, j);
						} else if (biomes[i][j] < lowest) {
							secondLowest = Math.min(secondLowest, lowest);
							lowest = biomes[i][j];
						}
					}
				}
			}
			
			/*trace("second lowest: " + secondLowest);
			trace("lowest: " + lowest);*/
			//trace("biome: " + biomes);
			
			// Add the reduced biome sets to the main list
			for (i = 0; i < biomes.length; i++) {
				for (j = 0; j < biomes[i].length; j++) {
					if (biomes[i][j] == secondLowest) {
						reducedBaseBiome[i][j] = 1;
					} else {
						if (biomes[i][j] != lowest) {
							var secondaryBiome:Array = [[0, 0], [0, 0]];
							secondaryBiome[i][j] = biomes[i][j];
							reducedBiomes.push(secondaryBiome);
						}
						reducedBaseBiome[i][j] = 0;
					}
				}
			}
			
			reducedBiomes.push(reducedBaseBiome);
			//trace(reducedBiomes);			
			return reducedBiomes;
		}
		
		private static function copyCombinedTile(reducedBiomes:Array, fullBiomes:Array, target:BitmapData, targetx:int, targety:int):void {
			
			copyBaseTile(reducedBiomes.pop(), fullBiomes, target, targetx, targety);
				
			
			//trace("remaining biomes to populate: " + reducedBiomes.length);
			while (reducedBiomes.length > 0) {
				copyTransparentTile(reducedBiomes.pop(), target, targetx, targety);
			}
		}
		
		private static function copyBaseTile(reducedBiome:Array, fullBiomes:Array, target:BitmapData, targetx:int, targety:int):void {
			//trace(reducedBiome);
			var frame:Point = diagonalTiles[reducedBiome] as Point;
			var defaultBiome:int = Biome.MOUNTAINS + 1;
			var firstBiome:int = defaultBiome;
			var secondBiome:int = defaultBiome;
			
			if (frame.x == 100) {
				WORLD_TILES.copyFrame(fullBiomes[0][0], Utility.randomNumber(0, 2), target, targetx, targety);
				return;
			}
			
			var bothSet:Boolean = false;
			for (var i:int = 0; i < fullBiomes.length; i ++) {
				for (var j:int = 0; j < fullBiomes[i].length; j++) {
					if (reducedBiome[i][j] == 0) {
						firstBiome = fullBiomes[i][j];
					} else if (reducedBiome[i][j] == 1) {
						secondBiome = fullBiomes[i][j];
					}
					
					if ((firstBiome != defaultBiome) && (secondBiome != defaultBiome)) {
						bothSet = true;
						break;
					}
				}
				
				if (bothSet) {
					break;
				}
			}
			
			getComboTile(firstBiome, secondBiome).copyFrame(frame.y, frame.x, target, targetx, targety);
			
		}
		
		private static function copyTransparentTile(reducedBiome:Array, target:BitmapData, targetx:int, targety:int):void {
			var frameSet:Boolean = false;
			var frame:Point = new Point(0, 0);
			for (var i:int = 0; i < reducedBiome.length; i ++) {
				for (var j:int = 0; j < reducedBiome[i].length; j++) {
					if (reducedBiome[i][j] != Biome.WATER) {
						if (i == 0) {
							frame = new Point(i, j);
							frameSet = true;
						} else {
							frame = new Point(2, j);
							frameSet = true;
						}
					}
					if (frameSet) {
						break;
					}
				}
				if (frameSet) {
					break;
				}
			}
			
			SpriteSheet(transTiles[reducedBiome[i][j]]).copyFrame(frame.y, frame.x, target, targetx, targety);
		}
		
		public function Tile() 
		{
			
		}
		
		
	}
	
}